package com.ebrothers.isns.map;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

import com.ebrothers.isns.common.API;
import com.ebrothers.isns.common.Constants;
import com.ebrothers.isns.util.HttpManager;

public abstract class Locator {
	private static final String TAG = "Locator";
	private LocationManager mLocationManager;
	private Context mContext;
	private OnLocationInfoRetrievedListener mListener;

	private LocationListener mLocationListener = new LocationListener() {
		public void onStatusChanged(String provider, int status, Bundle extras) {
			if (Constants.LOGD) {
				Log.d(TAG, "****** onStatusChanged. provider=" + provider
						+ ", status=" + status + ", extras=" + extras);
			}
		}

		public void onProviderEnabled(String provider) {
			if (Constants.LOGD) {
				Log.d(TAG, "****** onProviderEnabled. provider=" + provider);
			}
		}

		public void onProviderDisabled(String provider) {
			if (Constants.LOGD) {
				Log.d(TAG, "****** onProviderDisabled. provider=" + provider);
			}
		}

		public void onLocationChanged(Location location) {
			if (Constants.LOGD) {
				Log.d(TAG, "****** onLocationChanged. location=" + location);
			}
			onLocated(location);
		}
	};

	public Locator(Context context) {
		mContext = context;
		mLocationManager = (LocationManager) context
				.getSystemService(Context.LOCATION_SERVICE);
	}

	public Context getContext() {
		return mContext;
	}

	public LocationManager getLocationManager() {
		return mLocationManager;
	}

	public void requestLocationUpdates(String providerName) {
		mLocationManager.requestLocationUpdates(providerName, 1000, 0,
				mLocationListener);
	}

	public void removeUpdates() {
		mLocationManager.removeUpdates(mLocationListener);
	}

	protected abstract void onLocated(Location location);

	public abstract void locate();

	public void requestAddressInfoByLocation(Location location,
			OnLocationInfoRetrievedListener listener) {
		mListener = listener;
		String param = "latlng=" + location.getLatitude() + ","
				+ location.getLongitude() + "&sensor=false&language=zh";
		new LocationInfoRetriever().execute(API.GOOGLE_MAPS_IP + param);
	}

	class LocationInfoRetriever extends AsyncTask<String, Void, String> {

		@Override
		protected String doInBackground(String... params) {
			final HttpGet get = new HttpGet(params[0]);
			try {
				HttpResponse response = HttpManager.execute(get);
				int statusCode = response.getStatusLine().getStatusCode();
				if (HttpStatus.SC_OK == statusCode) {
					final HttpEntity entity = response.getEntity();
					if (entity != null) {
						String json = EntityUtils.toString(entity);
						entity.consumeContent();
						return json;
					}
				} else {
					Log.e(TAG,
							"****** Can't retrieve location name via google api. statusCode=["
									+ statusCode);
				}
			} catch (IOException e) {
				get.abort();
				Log.e(
								TAG,
								"****** Got an error when retrieving location name via google api.",
								e);
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			if (mListener != null) {
				mListener.onLocationInfoRetrieved(result);
			}
		}
	}

	public interface OnLocationInfoRetrievedListener {
		public void onLocationInfoRetrieved(String json);
	}
}
